<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8"/>
    <title>正交投影 & 透视投影</title>
    <script src="../assets/js/gl-utils.js"></script>
    <script src="../assets/js/gl-debug.js"></script>
    <script src="../assets/js/ice-utils.js"></script>
    <script src="../assets/js/gl-matrix/gl-matrix.js"></script>
    <script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
    <script type="text/javascript">
      // 顶点着色器
      const vertexString = `
        attribute vec4 a_Position;
        uniform mat4 u_MVPMatrix;
        attribute vec2 a_TexCoord;
        varying vec2 v_TexCoord;
        void main(void){
            gl_Position =  u_MVPMatrix * a_Position;
            v_TexCoord = a_TexCoord;
        }`;
      // 片元着色器
      const fragmentString = `
        precision mediump float;
        varying vec4 color;
        uniform sampler2D u_Sampler1;
        varying vec2 v_TexCoord;
        void main(void){
            gl_FragColor = texture2D(u_Sampler1, v_TexCoord);
        }`;
      let gl = null;
      let angle = 0;
      let canvas = null;
      let MVPMatrix = glMatrix.mat4.create();
      let projMatrix = glMatrix.mat4.create();
      let u_MVPMatrix = null;

      function main() {
        initWebgl();
        initShaders(gl, vertexString, fragmentString);
        initBuffer();
        initEvent();
      }

      function initWebgl() {
        // 获取canvas对象
        canvas = document.getElementById('webgl');
        //获取webgl绘制对象
        gl = getWebGLContext(canvas);
      };

      function initBuffer() {
        // Create a cube
        //    v6----- v5
        //   /|      /|
        //  v1------v0|
        //  | |     | |
        //  | |v7---|-|v4
        //  |/      |/
        //  v2------v3
        const coordinates = new Float32Array([   // Vertex coordinates
          1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,    // 前
          1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,    // 右
          1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0,    // 上
          -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0,    // 左
          -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,    // 下
          1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0     // 后
        ]);
        const texCoords = new Float32Array([   // 纹理坐标
          1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,    // 前
          0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0,    // 右
          1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,    // 上
          1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,    // 左
          0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,    // 下
          0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0     // 后
        ]);
        // 索引数组
        const indices = new Uint8Array([
          0, 1, 2, 0, 2, 3,    // 前
          4, 5, 6, 4, 6, 7,    // 右
          8, 9, 10, 8, 10, 11,    // 上
          12, 13, 14, 12, 14, 15,    // 左
          16, 17, 18, 16, 18, 19,    // 下
          20, 21, 22, 20, 22, 23     // 后
        ]);
        // 然后把数据填充的各自的缓冲区中
        initArrayBuffer(gl, coordinates, 3, gl.FLOAT, 'a_Position');
        initArrayBuffer(gl, texCoords, 2, gl.FLOAT, 'a_TexCoord');
        // 释放缓冲区中的数据
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
        // 将索引数据写入到缓冲区中
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
        //数据写入
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
        glMatrix.mat4.perspective(projMatrix, 30.0, canvas.width / canvas.height, 1.0, 100.0);
        setTranslate(gl, 0, 0, 0, projMatrix);
        initTextures(gl, indices.length, 'u_Sampler1', '../assets/image/box.png');
      }

      function initArrayBuffer(gl, data, num, type, attribute) {
        // 把数据写入到缓冲区中
        gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
        gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
        const a_attribute = gl.getAttribLocation(gl.program, attribute);
        // 将图元分配到图元装配空间中去，并存储起来
        gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
        // 开启图元装配
        gl.enableVertexAttribArray(a_attribute);
        return true;
      }

      function initEvent() {
        tBtn.onclick = function (e) {
          gl.clearColor(0.0, 0.0, 0.0, 1.0);
          gl.clear(gl.COLOR_BUFFER_BIT);
          glMatrix.mat4.perspective(projMatrix, 30.0, canvas.width / canvas.height, 1.0, 100.0);
          setTranslate(gl, 0, 0, 0, projMatrix);
          gl.uniformMatrix4fv(u_MVPMatrix, false, MVPMatrix);
          gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_BYTE, 0);
        };
        zBtn.onclick = function (e) {
          gl.clearColor(0.0, 0.0, 0.0, 1.0);
          gl.clear(gl.COLOR_BUFFER_BIT);
          glMatrix.mat4.ortho(projMatrix, -1, 1, -1, 1, -1, 100);
          setTranslate(gl, 0, 0, 0, projMatrix);
          gl.uniformMatrix4fv(u_MVPMatrix, false, MVPMatrix);
          gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_BYTE, 0);
        };
      }

      function initTextures(gl, n, u_sample, url) {
        let texture = gl.createTexture();
        let u_Sampler = gl.getUniformLocation(gl.program, u_sample);
        let image = new Image();
        image.onload = function () {
          loadTexture(gl, n, texture, u_Sampler, image);
        };
        image.src = url;
        return true;
      }

      function setTranslate(gl, x, y, z, projMatrix) {
        let viewMatrix = glMatrix.mat4.create();
        // 相机矩阵
        glMatrix.mat4.lookAt(viewMatrix, [0.0, 0.0, 3], [x, y, z], [0.0, 1.0, 0.0]);
        let modelMatrix = glMatrix.mat4.create();
        u_MVPMatrix = gl.getUniformLocation(gl.program, 'u_MVPMatrix');
        MVPMatrix = glMatrix.mat4.create();
        glMatrix.mat4.multiply(MVPMatrix, projMatrix, glMatrix.mat4.multiply(MVPMatrix, viewMatrix, modelMatrix));
        gl.uniformMatrix4fv(u_MVPMatrix, false, MVPMatrix);
      }

      function loadTexture(gl, n, texture, u_Sampler, image) {
        // 图像y轴翻转
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
        gl.uniform1i(u_Sampler, 0);
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.uniformMatrix4fv(u_MVPMatrix, false, MVPMatrix);
        gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
      }
    </script>
</head>

<body onload="main()">
<canvas id="webgl" width="512" height="512">
</canvas>

<input type="button" id="zBtn" style="width:80px;position:absolute;top:550px;left:20px;cursor: pointer;"
       value="正交投影"/>
<input type="button" id="tBtn" style="width:80px;position:absolute;top:550px;left:180px;cursor: pointer;"
       value="透视投影"/>
</body>

</html>